/*
 * ============================================
 * Identifiers
 * ============================================
 */

fn main() {
  abc;
}

/*
 * ============================================
 * Raw identifiers
 * ============================================
 */

fn main() {
  (r#abc as r#Def).r#ghi;
}

/*
 * ============================================
 * Unary operator expressions
 * ============================================
 */

fn main() {
  -num;
  !bits;
  *boxed_thing;
}

/*
 * ============================================
 * Reference expressions
 * ============================================
 */

fn main() {
  &a;
  &mut self.name;
}

/*
 * ============================================
 * Try expressions
 * ============================================
 */

fn main() {
  a.unwrap()?;
}

/*
 * ============================================
 * Binary operator expressions
 * ============================================
 */

fn main() {
  a * b;
  a / b;
  a % b;
  a + b;
  a - b;
  a >> b;
  a << b;
  a == b;
  a && b;
  a || b;
}

/*
 * ============================================
 * Grouped expressions
 * ============================================
 */

fn main() {
  (0);
  (2 * (3 + 4));
}

/*
 * ============================================
 * Range expressions
 * ============================================
 */

fn main() {
  1..2;
  3..;
  ..4;
  ..;
  1..b;
  a..b;
}

/*
 * ============================================
 * Assignment expressions
 * ============================================
 */

fn main() {
  x = y;
}

/*
 * ============================================
 * Compound assignment expressions
 * ============================================
 */

fn main() {
  x += 1;
  x += y;
}

/*
 * ============================================
 * Type cast expressions
 * ============================================
 */

fn main() {
  1000 as u8;
  let character = integer as char;
  let size: f64 = len(values) as f64;
}

/*
 * ============================================
 * Call expressions
 * ============================================
 */

fn main() {
  foo();
  add(1i32, 2i32);
  add(
      1i32,
      2i32,
  );
}

/*
 * ============================================
 * Array expressions
 * ============================================
 */

fn main() {
  [];
  [1, 2, 3];
  ["a", "b", "c"];
  [0; 128];
}

/*
 * ============================================
 * Tuple expressions
 * ============================================
 */

fn main() {
  ();
  (0,);
  let (x, y, z) = (1, 2, 3);
}

/*
 * ============================================
 * Struct expressions
 * ============================================
 */

fn main() {
  NothingInMe {};
  Point {x: 10.0, y: 20.0};
  let a = SomeStruct { field1, field2: expression, field3, };
  let u = game::User {name: "Joe", age: 35, score: 100_000};
}

/*
 * ============================================
 * Struct expressions with update initializers
 * ============================================
 */

fn main() {
  let u = User{name, ..current_user()};
}

/*
 * ============================================
 * If expressions
 * ============================================
 */

fn main() {
  if n == 1 {
  } else if n == 2 {
  } else {
  }
}

fn main() {
  let y = if x == 5 { 10 } else { 15 };
}

/*
 * ============================================
 * If let expressions
 * ============================================
 */

fn main() {
  if let ("Bacon", b) = dish {
  }
}

/*
 * ============================================
 * While let expressions
 * ============================================
 */

fn main() {
  while let ("Bacon", b) = dish {
  }
}

/*
 * ============================================
 * Match expressions
 * ============================================
 */

fn main() {
  match x {
      1 => { "one" }
      2 => "two",
      -1 => 1,
      -3.14 => 3,

      #[attr1]
      3 => "three",
      macro!(4) => "four",
      _ => "something else",
  }

  let msg = match x {
      0 | 1 | 10 => "one of zero, one, or ten",
      y if y < 20 => "less than 20, but not zero, one, or ten",
      y if y == 200 =>
        if a {
          "200 (but this is not very stylish)"
        }
      _ => "something else",
  };
}

/*
 * ============================================
 * While expressions
 * ============================================
 */

fn main() {
  while !done {
    done = true;
  }
}

/*
 * ============================================
 * Loop expressions
 * ============================================
 */

fn main() {
  'outer: loop {
    'inner: loop {
      break 'outer;
      break true;
    }
  }
}

/*
 * ============================================
 * For expressions
 * ============================================
 */

fn main() {
  for e in v {
    bar(e);
  }

  for i in 0..256 {
    bar(i);
  }

  'outer: for x in 0..10 {
      'inner: for y in 0..10 {
          if x % 2 == 0 { continue 'outer; }
          if y % 2 == 0 { continue 'inner; }
      }
  }
}

/*
 * ============================================
 * Field expressions
 * ============================================
 */

fn main() {
  mystruct.myfield;
  foo().x;
  value.0.1.iter();
  1.max(2);
}

/*
 * ============================================
 * Method call expressions
 * ============================================
 */

fn main() {
  mystruct.foo();
}

/*
 * ============================================
 * Index expressions
 * ============================================
 */

fn main() {
  ([1, 2, 3, 4])[0];
  arr[10];
  arr[n];
}

/*
 * ============================================
 * Scoped functions
 * ============================================
 */

fn main() {
  a::b();
  C::<D>::e();
  ::f();
  ::g::h();
  crate::foo();
  super::foo();
}

/*
 * ============================================
 * Scoped functions with fully qualified syntax
 * ============================================
 */

fn main() {
  <Dog as Animal>::eat(d);
}

/*
 * ============================================
 * Scoped functions with macros as types
 * ============================================
 */

fn main() {
  <Token![]>::foo();
}

/*
 * ============================================
 * Generic functions
 * ============================================
 */

fn main() {
  std::sizeof::<u32>();
  foo::<8>();
}

/*
 * ===========================================
 * Closures
 * ===========================================
 */

fn main() {
  a.map(|(b, c)| b.push(c));
  d.map(move |mut e| {
      f(e);
      g(e)
  });
  h(|| -> i { j });
}

/*
 * ===========================================
 * Closures with typed parameters
 * ===========================================
 */

fn main() {
  a.map(|b: usize| b.push(c));
}

/*
 * ===========================================
 * Unsafe blocks
 * ===========================================
 */

fn main() {
  const a : A = unsafe { foo() };
}

/*
 * ===========================================
 * Inline const or Const blocks as expression
 * ===========================================
 */

fn main() {
  const { 1 + 3 };
  if *x < 0 { const { &4i32.pow(4) } } else { x }
  let three_ranges = [const { (0..=5).into_inner() }; 3];
}
